package com.lee.common.network

import android.net.ParseException
import androidx.lifecycle.LiveData
import com.google.gson.JsonParseException
import org.json.JSONException
import retrofit2.*
import java.lang.reflect.Type
import java.net.ConnectException
import java.util.concurrent.atomic.AtomicBoolean

//对应HTTP的状态码
private const val UNAUTHORIZED = 401
private const val FORBIDDEN = 403
private const val NOT_FOUND = 404
private const val REQUEST_TIMEOUT = 408
private const val INTERNAL_SERVER_ERROR = 500
private const val BAD_GATEWAY = 502
private const val SERVICE_UNAVAILABLE = 503
private const val GATEWAY_TIMEOUT = 504

const val CONNECT_EXCEPTION_CODE = 20001
const val HTTP_EXCEPTION_CODE = 20002

class LiveDataCallAdapter<T>(
    private val responseType: Type,
    var creator: (Int, String, Any?) -> Any
) :
    CallAdapter<T, LiveData<T>> {
    override fun adapt(call: Call<T>): LiveData<T> {
        return object : LiveData<T>() {
            private val started = AtomicBoolean(false)
            override fun onActive() {
                super.onActive()
                if (started.compareAndSet(false, true)) {//确保执行一次
                    call.enqueue(object : Callback<T> {
                        override fun onFailure(call: Call<T>, t: Throwable) {
                            var errorMessage = t.message
                            var errorCode = -1
                            if (t is HttpException) { //HTTP错误
                                when (t.code()) {
                                    UNAUTHORIZED, FORBIDDEN, NOT_FOUND, REQUEST_TIMEOUT, GATEWAY_TIMEOUT, INTERNAL_SERVER_ERROR, BAD_GATEWAY, SERVICE_UNAVAILABLE -> {
                                        errorMessage = "网络连接失败,请检查网络设置" //均视为网络错误
                                        errorCode = HTTP_EXCEPTION_CODE         //t.code()
                                    }
                                }
                            } else if (t is ConnectException) {
                                errorMessage = "网络连接失败,请检查网络设置"
                                errorCode = CONNECT_EXCEPTION_CODE
                            } else if (t is JsonParseException
                                || t is JSONException
                                || t is ParseException
                            ) {
                                errorMessage = "解析错误" //均视为解析错误
                            } else {
                                errorMessage = "未知错误"
                            }
                            val value = creator(errorCode, errorMessage ?: "", null) as T
                            postValue(value)
                        }

                        override fun onResponse(
                            call: Call<T>,
                            response: Response<T>
                        ) {
                            postValue(response.body())
                        }
                    })
                }
            }
        }
    }

    override fun responseType() = responseType
}